import express from 'express';
import config from 'config'; // see https://github.com/motdotla/dotenv#how-do-i-use-dotenv-with-import
import cookieParser from 'cookie-parser';
import morgan from 'morgan';
import cors from 'cors';
import { createProxyMiddleware } from 'http-proxy-middleware';

import authNCloud from './middlewares/auth-ncloud';
import authCheck from './middlewares/auth-check';

import errorHandle from './middlewares/error-handle';

// 全局异常处理
process.on('unhandledRejection', (reason, p) => {
  console.log('Unhandled Rejection at: Promise ', p, ' reason: ', reason);
  // application specific logging, throwing an error, or other logic here
});

process.on('uncaughtException', (err) => {
  console.log('Caught exception: ', err);
});

const app = express();
app.use(morgan('combined'));

app.use(cors());

// parse application/x-www-form-urlencoded
app.use(express.urlencoded({ limit: '10mb', extended: false }));

// parse application/json
app.use(express.json({ limit: '10mb' }));

// parse cookie
app.use(cookieParser());

// Java API 代理
const javaApiProxy = createProxyMiddleware({
  target: 'https://devtest.vonmall.cn:50081', // Java Web API
  changeOrigin: true,
  // pathRewrite: { '^/': '/bank' },
  secure: false,
  logger: console,
  on: {
    proxyReq(proxyReq, req, res) {
      if (req.user) {
        proxyReq.setHeader('X-User-Id', req.user.id);
        proxyReq.setHeader('X-User-Role', req.user.user_type || '');
        proxyReq.setHeader('X-User-Name', req.user.login_name);
      }
      proxyReq.setHeader('X-From-Gateway', 'NCloud-Gateway');

      if (req.body && Object.keys(req.body).length) {
        const bodyData = JSON.stringify(req.body);
        // 重新写入 body
        proxyReq.setHeader('Content-Type', 'application/json');
        proxyReq.setHeader('Content-Length', Buffer.byteLength(bodyData));
        proxyReq.write(bodyData);
        proxyReq.end();
      }
    },
    error(err, req, res) {
      console.log(err);
      res.status(500).send(`Proxy failed: ${err.message}`);
    },
  },
});

// Java API production 代理
const javaApiProxy2 = createProxyMiddleware({
  target: 'https://pos.no-pms.com', // Java Web API
  changeOrigin: true,
  // pathRewrite: { '^/': '/bank' },
  secure: false,
  logger: console,
  on: {
    proxyReq(proxyReq, req, res) {
      if (req.user) {
        proxyReq.setHeader('X-User-Id', req.user.id);
        proxyReq.setHeader('X-User-Role', req.user.user_type || '');
        proxyReq.setHeader('X-User-Name', req.user.login_name);
      }
      proxyReq.setHeader('X-From-Gateway', 'NCloud-Gateway');

      if (req.body && Object.keys(req.body).length) {
        const bodyData = JSON.stringify(req.body);
        // 重新写入 body
        proxyReq.setHeader('Content-Type', 'application/json');
        proxyReq.setHeader('Content-Length', Buffer.byteLength(bodyData));
        proxyReq.write(bodyData);
        proxyReq.end();
      }
    },
    error(err, req, res) {
      console.log(err);
      res.status(500).send(`Proxy failed: ${err.message}`);
    },
  },
});

// Core API 代理
const coreApiProxy = createProxyMiddleware({
  target: 'https://admin.no-pms.com', // Core API
  changeOrigin: true,
  pathRewrite: {
    '^/': '/pro-api/', // add base path
  },
  secure: false,
  logger: console,
  on: {
    proxyReq(proxyReq, req, res) {
      if (req.body && Object.keys(req.body).length) {
        const bodyData = JSON.stringify(req.body);
        // 重新写入 body
        proxyReq.setHeader('Content-Type', 'application/json');
        proxyReq.setHeader('Content-Length', Buffer.byteLength(bodyData));
        proxyReq.write(bodyData);
        proxyReq.end();
      }
    },
    error(err, req, res) {
      console.log(err);
      res.status(500).send(`Proxy failed: ${err.message}`);
    },
  },

});

app.use('/v1', authNCloud, coreApiProxy);
app.use('/v2', authCheck, javaApiProxy);
app.use('/pro', authCheck, javaApiProxy2);

app.get('/', (req, res) => {
  res.send('NCloud Gateway 服务运行中...');
});

// 错误处理

app.use(errorHandle);

const port = process.env.port || config.get('port') || 3000;

app.listen(port, () => {
  console.log(`Server is running at http://localhost:${port}`);
});
